﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace  Logic
{
    internal sealed class Encryption
    {
        static private byte[] KEYS = new byte[8];
        static private byte[] HASH = new byte[8];

        public static string EncriptData(string data, string key)
        {

            string response;
            if (data.Length > 92160)
            {
                response = null;
                return response;
            }


            if (!StartKey(key))
            {
                response = null;
                return response;
            }

            data = string.Format("{0,5:00000}" + data, data.Length);

            byte[] rbData = new byte[data.Length];
            ASCIIEncoding aEnc = new ASCIIEncoding();
            aEnc.GetBytes(data, 0, data.Length, rbData, 0);

            DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();

            ICryptoTransform desEncrypt = descsp.CreateEncryptor(KEYS, HASH);

            MemoryStream entrada = new MemoryStream(rbData);
            CryptoStream cs = new CryptoStream(entrada, desEncrypt, CryptoStreamMode.Read);
            MemoryStream mSalida = new MemoryStream();

            int BytesLeidos;
            byte[] exit = new byte[1024];
            do
            {
                BytesLeidos = cs.Read(exit, 0, 1024);
                if (BytesLeidos != 0)
                {
                    mSalida.Write(exit, 0, BytesLeidos);
                }
            } while (BytesLeidos > 0);

            if (mSalida.Length == 0)
            {
                response = "";
            }
            else
            {
                response = Convert.ToBase64String(mSalida.GetBuffer(), 0, (int)mSalida.Length);
            }

            return response;
        }

        public static string DecryptData(string data, string key)
        {
            string response;


            if (!StartKey(key))
            {
                response = null;
                return response;
            }


            int ret = 0;
            DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();
            ICryptoTransform desDecrypt = descsp.CreateDecryptor(KEYS, HASH);

            MemoryStream exit = new MemoryStream();
            CryptoStream cs = new CryptoStream(exit, desDecrypt, CryptoStreamMode.Write);

            byte[] reversa = new byte[data.Length];
            try
            {
                reversa = Convert.FromBase64CharArray(data.ToCharArray(), 0, data.Length);
            }
            catch (Exception)
            {
                response = null;
                return response;
            }

            long leido = 0;
            long total = data.Length;

            try
            {

                while (total >= leido)
                {
                    cs.Write(reversa, 0, (int)reversa.Length);

                    leido = exit.Length + Convert.ToUInt32(((reversa.Length / descsp.BlockSize) * descsp.BlockSize));
                };

                ASCIIEncoding aEnc = new ASCIIEncoding();
                response = aEnc.GetString(exit.GetBuffer(), 0, (int)exit.Length);

                string pCinco = response.Substring(0, 5);
                int nLen = Convert.ToInt32(pCinco);
                response = response.Substring(5, nLen);
                ret = (int)exit.Length;

                return response;
            }
            catch (Exception)
            {
                response = null;
                return response;
            }
        }

        private static bool StartKey(string key)
        {
            try
            {

                byte[] byteKey = new byte[key.Length];
                ASCIIEncoding aEnc = new ASCIIEncoding();
                aEnc.GetBytes(key, 0, key.Length, byteKey, 0);

                SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
                byte[] aHash = sha.ComputeHash(byteKey);

                byte i;

                for (i = 0; i < 8; i++)
                {
                    KEYS[i] = aHash[i];
                }

                for (i = 8; i < 16; i++)
                {
                    HASH[i - 8] = aHash[i];
                }

                return true;
            }
            catch (Exception)
            {

                return false;
            }
        }
    }

}
